﻿using ConfExpert.Forms.Base;
using DevExpress.Utils;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
using DevTeamIT;
using ITaskManager.Datasets;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace ConfExpert.Utility
{
    public class RepositoryManager
    {
        //desc. Bu açıklama, örnek olsun diye eklendi.

        //if (Session.CurrentUser.UserId == 17)
        //{
        //    System.Collections.IDictionary statistics = (sel.Connection as SqlConnection).RetrieveStatistics();
        //    AppSession.MainForm.NotifyMain(string.Format("BytesReceived: {0:###,#}", statistics["BytesReceived"]));
        //}

        DateTime MxA, MxK, Mx;
        public RepositoryManager()
        {
            //try
            //{
            //    MxA = MxK = Mx = new DateTime(2000, 1, 1);

            //    if (File.Exists(Session.sqlitefileDelete))
            //    {
            //        //impl. @05.04.2015
            //        File.Delete(Session.sqlitefile);
            //        File.Delete(Session.sqlitefileDelete);
            //    }
            //    else
            //    {
            //        //impl. @23.01.2015
            //        string connstr = "Data Source=" + Session.sqlitefile;    // +"; PRAGMA synchronous=off; PRAGMA journal_mode = MEMORY";
            //        if (File.Exists(Session.sqlitefile))
            //            using (var con = new SQLiteConnection(connstr))
            //            {
            //                con.Open();

            //                var sqlAdapter = new SQLiteDataAdapter("SELECT * FROM V_Kumas", con);
            //                DataTable table = new DataTable();
            //                sqlAdapter.Fill(table);
            //                RepositoryManager.dsi.V_Kumas.Merge(table);
            //                MxK = (DateTime)RepositoryManager.dsi.V_Kumas.Compute("MAX(ModifiedOn)", string.Empty);

            //                sqlAdapter = new SQLiteDataAdapter("SELECT * FROM V_Aksesuar", con);
            //                table = new DataTable();
            //                sqlAdapter.Fill(table);
            //                RepositoryManager.dsi.V_Aksesuar.Merge(table);
            //                MxA = (DateTime)RepositoryManager.dsi.V_Aksesuar.Compute("MAX(ModifiedOn)", string.Empty);
            //            }

            //        Mx = MxK > MxA ? MxK : MxA;
            //    }
            //}
            //catch
            //{
            //    using (FileStream fs = File.Create(Session.sqlitefileDelete))
            //    {
            //        Byte[] info = new UTF8Encoding(true).GetBytes("sqlite file corrupted.");
            //        fs.Write(info, 0, info.Length);
            //    }

            //    XtraMessageBox.Show("Program yeniden başladığında tekrar login olmayı deneyin.", "Başlatma dosyasında hata");
            //    return;
            //}


            //MyData NewMyData = RefreshData(Mx);
            RepositoryManager.dsi.Merge(RefreshData(Mx));
            RepositoryManager.RemoveAllDeletedRows();

            
            Initialize();   //OA.1
        }

        public MyData RefreshData(DateTime LastModified_KA)
        {
            try
            {
                DataSet updates = GetUpdates(LastModified_KA, GetLastModified());

                MyData.IT_LookupDataTable LookUp = new MyData.IT_LookupDataTable();
                LookUp.Merge(updates.Tables[0]);
                MyData NewMyData = new MyData();

                if (LookUp.Rows.Count > 0)
                {
                    NewMyData.EnforceConstraints = false;
                    NewMyData.IT_Lookup.Merge(LookUp);
                    for (int i = 0; i < LookUp.Rows.Count; i++)
                    {
                        string TABLE_NAME = LookUp.Rows[i]["TABLE_NAME"].ToString();
                        NewMyData.Tables[TABLE_NAME].Merge(updates.Tables[i + 1]);
                    }
                }

                NewMyData.Tables["Settings"].Merge(updates.Tables[LookUp.Rows.Count + 1]);

                return NewMyData;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public MyData RefreshData()
        {
            try
            {
                DataSet updates = GetUpdates(GetLastModified(), GetLastModified());

                MyData.IT_LookupDataTable LookUp = new MyData.IT_LookupDataTable();
                LookUp.Merge(updates.Tables[0]);
                MyData NewMyData = new MyData();

                if (LookUp.Rows.Count > 0)
                {
                    NewMyData.EnforceConstraints = false;
                    NewMyData.IT_Lookup.Merge(LookUp);
                    for (int i = 0; i < LookUp.Rows.Count; i++)
                    {
                        string TABLE_NAME = LookUp.Rows[i]["TABLE_NAME"].ToString();
                        NewMyData.Tables[TABLE_NAME].Merge(updates.Tables[i + 1]);
                    }
                }

                NewMyData.Tables["Settings"].Merge(updates.Tables[LookUp.Rows.Count + 1]);

                return NewMyData;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public RepositoryItem this[Rp repository]
        {
            get
            {
                return Get(repository);
            }
        }

        public static void RemoveAllDeletedRows()
        {
            RemoveDeletedRows(-1);
            LastDeletedRowsId = GetLastLocalDeletedRowsId();
        }

        private static int GetLastLocalDeletedRowsId()
        {
            if (dsi.DeletedRows.Count > 0)
                return (int)dsi.DeletedRows.Compute("MAX(DeletedRowsId)", "");
            else
                return -1;
        }
        public static int LastDeletedRowsId = -1;
        public static void RemoveDeletedRows()
        {

            int CurrentDeletedRowsId = GetLastLocalDeletedRowsId();
            if (LastDeletedRowsId != CurrentDeletedRowsId)
            {
                RemoveDeletedRows(LastDeletedRowsId);
                LastDeletedRowsId = CurrentDeletedRowsId;
            }
        }

        public static void RemoveDeletedRows(int LastDeletedRowsId)
        {
            DataTable dtDeleted = Session.DataManager.ExecuteDataTable("IT_GetDeletedRows", LastDeletedRowsId);
            foreach (DataRow drDeleted in dtDeleted.Rows)
            {
                string tableName = drDeleted["TABLE_NAME"] as string;
                string ids = (string)drDeleted["Ids"];

                DataTable riTable = RepositoryManager.dsi.Tables[tableName];
                DataRow[] drsToDelete = riTable.Select(string.Format("{0} in ({1})", riTable.PrimaryKey[0].ColumnName, ids));
                foreach (DataRow drToDelete in drsToDelete)
                    riTable.Rows.Remove(drToDelete);
            }
        }

        public static MyData dsi = new MyData();

        static Dictionary<int, RepositoryItem> repositories = new Dictionary<int, RepositoryItem>();

        public static RepositoryItem Get(int LookUpId)
        {
            RepositoryItem ri;
            repositories.TryGetValue(LookUpId, out ri);
            return ri;
        }

        public static int GetIndexOf(RepositoryItem ri)
        {
            if (ri != null)
                if (repositories.ContainsValue(ri))
                    return repositories.FirstOrDefault(x => x.Value == ri).Key;

            return 0;
        }

        public static RepositoryItem Get(Rp repository)
        {
            return repositories[(int)repository];
        }

        DataSet GetUpdates(DateTime LastModified_KA, DateTime LastModified)
        {
            using (SqlConnection sqlConn = new SqlConnection(Session.DataManager.ConnectionString))
            {
                SqlCommand sqlCmd = sqlConn.CreateCommand();
                sqlCmd.CommandText = "IT_GetUpdates";
                sqlCmd.CommandTimeout = 90;
                sqlCmd.CommandType = CommandType.StoredProcedure;

                SqlParameter[] parameters = new SqlParameter[2];
                parameters[0] = new SqlParameter("@UserId", SqlDbType.Int);
                parameters[0].Value = Session.WhoAmI;
                parameters[1] = new SqlParameter("@LastModified", SqlDbType.DateTime);
                parameters[1].Value = LastModified;
                sqlCmd.Parameters.AddRange(parameters);

                try
                {
                    DataSet dsx = new DataSet();
                    DbDataAdapter sqlda = Session.DataManager.Database.GetDataAdapter();
                    sqlda.SelectCommand = sqlCmd;
                    sqlda.Fill(dsx);
                    return dsx;
                }
                catch (Exception Ex)
                {
                    throw (Ex);
                }
            }
        }

        static DateTime LastModified;

        public static DateTime GetLastModified()
        {
            LastModified = new DateTime(2000, 1, 1);
            foreach (MyData.IT_LookupRow lu in dsi.IT_Lookup)
                if (lu.LastModified > LastModified)
                    LastModified = lu.LastModified;
            return LastModified;
        }


        public static RepositoryItemPictureEdit GetPhotoRI()
        {
            RepositoryItemPictureEdit ri = new RepositoryItemPictureEdit();
            ri.SizeMode = PictureSizeMode.Zoom;
            ri.NullText = " ";
            ri.Padding = new Padding(-1);
            ri.PictureStoreMode = PictureStoreMode.ByteArray;
            return ri;
        }

        public static RepositoryItemTextEdit MaskedNumeric(int digits = 0)
        {
            RepositoryItemTextEdit ri = new RepositoryItemTextEdit();
            ri.AutoHeight = false;
            ri.Mask.EditMask = "f" + digits.ToString();
            ri.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric;
            //ri.Mask.UseMaskAsDisplayFormat = true;            
            return ri;
        }


        //public RepositoryItem GetFieldRI(string fieldName)

        public void Initialize()
        {
            XForm x = new XForm();

            // İç içe geçmiş sütunlarda, sırasız gidebilmek için önce tüm RI ler ekleniyor, sonra içleri güncelleniyor.

            foreach (MyData.IT_LookupRow drLookup in dsi.IT_Lookup.Rows)
            {
                DataTable dt = dsi.Tables[drLookup.TABLE_NAME];
                RepositoryItemGridLookUpEdit ri = GetGLESablon(dt, drLookup.DisplayMember, drLookup.ValueMember);
                repositories.Add(drLookup.LookUpId, ri);
            }

            DataTable dtCols = Session.DataManager.ExecuteDataTable("IT_GetLookUps1");

            foreach (MyData.IT_LookupRow drLookup in dsi.IT_Lookup.Rows)
            {
                DataTable dt = dsi.Tables[drLookup.TABLE_NAME];
                RepositoryItemGridLookUpEdit ri = (RepositoryItemGridLookUpEdit)repositories[drLookup.LookUpId];
                ri.View.BeginUpdate();
                ri.PopupFilterMode = AppSession.Settings.PopupFilterMode;

                foreach (DataRow lkCol in dtCols.Select("LookUpId =" + drLookup.LookUpId))
                {
                    string f = lkCol["FieldName"].ToString();
                    GridColumn gridCol = ri.View.Columns[f];

                    switch (f)
                    {
                        case "isPreferred":
                        case "ModifiedOn":
                        case "Deleted":
                        case "UserId":
                        case "TS":
                        case "Hue":
                        case "nFirmaId":
                        case "Tags":
                        case "RaporBoyuId":
                        case "CheckedOn":
                            gridCol.Visible = false;
                            break;
                        default:

                            if (f == "Name")
                                gridCol.Caption = drLookup.TABLE_NAME;
                            else if (f != "PhotoMikro")   //PhotoMikro, "GetGLESablon da yapılıyor";
                                gridCol.Caption = f;

                            //if (lkCol.FieldName == "VendorId" &&
                            //    drLookup.TABLE_NAME == "Vendor")
                            //    drLookup.TABLE_NAME = drLookup.TABLE_NAME;

                            if (ri.View.Columns.IndexOf(gridCol) > 0)
                                x.MapGridColumn(gridCol);
                            else
                            {
                                gridCol.Caption = "#";
                                gridCol.OptionsColumn.AllowEdit = false;
                                gridCol.AppearanceCell.BackColor = System.Drawing.Color.LightYellow;
                            }

                            //if (!lkCol.IsRepositoryIdNull())
                            //    gridCol.ColumnEdit = RepositoryManager.Get(lkCol.RepositoryId);

                            break;
                    }
                }

                if (ri.View.Columns.Contains(ri.View.Columns["Deleted"]))
                {
                    foreach (DataRow z in dsi.Tables[drLookup.TABLE_NAME].Select("Deleted=1"))
                        dsi.Tables[drLookup.TABLE_NAME].Rows.Remove(z);

                    ri.View.RowStyle += new RowStyleEventHandler(gridview_RowStyle);
                }

                ri.View.EndUpdate();

            }



            DataTable dtEL = Session.DataManager.ExecuteDataTable("GetEnvanterLokasyon");
            riEL = RepositoryManager.GetGLESablon(dtEL, "Name", "IT_LokasyonId");

            DataTable dtEA = Session.DataManager.ExecuteDataTable("GetEnvanterAlan");
            riEA = RepositoryManager.GetGLESablon(dtEA, "Name", "IT_AlanId");

            DataTable dtEC = Session.DataManager.ExecuteDataTable("GetEnvanterCesit");
            riEC = RepositoryManager.GetGLESablon(dtEC, "Name", "IT_EnvanterCesitId");

            DataTable dtCT = Session.DataManager.ExecuteDataTable("GetCihazTipi");
            riCT = RepositoryManager.GetGLESablon(dtCT, "Name", "IT_CihazTipiId");

            riYaziciTipi.Items.AddRange(new object[] { "MonoCrome Yazıcı", "Renkli Yazıcı", "Çok Fonksiyonlu Yazıcı" });
            riYaziciTipi.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;

            riBaglantiTipi.Items.AddRange(new object[] { "USB", "Ethernet", "Serial" });
            riBaglantiTipi.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;

            riKagitBoyutu.Items.AddRange(new object[] { "A3", "A4" });
            riKagitBoyutu.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;
        }

        public static RepositoryItemGridLookUpEdit GetGLESablon(DataTable SourceTable, string DisplayMember, string ValueMember)
        {
            RepositoryItemGridLookUpEdit gleSablon = new RepositoryItemGridLookUpEdit();
            gleSablon.PopupFilterMode = AppSession.Settings.PopupFilterMode;

            //search columns via the View's OptionsFind.FindFilterColumns property. In the "StartsWith" or "Contains" mode, the search is performed against a field specified by the RepositoryItemSearchLookUpEdit.DisplayMember property.

            gleSablon.AllowNullInput = DefaultBoolean.True;
            gleSablon.View.OptionsView.ColumnAutoWidth = false;
            //gleSablon.View.OptionsView.EnableAppearanceEvenRow = Session.SettingsEnableAppearanceEvenRow;
            gleSablon.View.OptionsView.ShowAutoFilterRow = true;
            gleSablon.View.OptionsBehavior.Editable = false;
            gleSablon.View.BestFitMaxRowCount = 50;
            gleSablon.View.OptionsFind.HighlightFindResults = true;
            gleSablon.View.OptionsSelection.MultiSelectMode = GridMultiSelectMode.RowSelect;
            gleSablon.TextEditStyle = TextEditStyles.Standard; // DisableTextEditor;
            gleSablon.NullText = string.Empty;
            gleSablon.ImmediatePopup = true;

            gleSablon.PopupFormMinSize = new Size(500, 500);
            gleSablon.BestFitMode = BestFitMode.BestFit;

            gleSablon.Popup += gleSablon_Popup;

            //Form2.LookUpEdit.Properties.BestFitMode = BestFitMode.BestFitResizePopup;
            //Form2.LookUpEdit.Properties.SearchMode = SearchMode.AutoComplete;
            //Form2.LookUpEdit.Properties.AutoSearchColumnIndex = 1;
            //ri.View.OptionsFind.AllowFindPanel = true;
            //ri.View.OptionsView.AllowCellMerge = true;
            //riMaster.AutoComplete = false;            
            //riMaster.ShowDropDown = ShowDropDown.DoubleClick;
            //I have a ComboBoxEdit with AutoComplete=True and TextEditStyle=DisableTextEditor. When the user starts typing and a matching item is found the selection changes to that item, with the series of matching characters hightlighted. Is there a way to get that hightlighted text? 
            //The same suggestion is applied to the ProgressBarControl: it must always use the DisplayFormat and CustomDisplayText regardless of its focused state, because it's a "read-only editor".

            gleSablon.DataSource = SourceTable;
            gleSablon.DisplayMember = DisplayMember;
            gleSablon.ValueMember = ValueMember;

            gleSablon.PopulateViewColumns();


            //if (SourceTable.TableName == "V_Kumas")
            //{
            //    gleSablon.View.Columns["FinishId"].Caption = "Finish";
            //    gleSablon.View.Columns["KaliteAciklama"].Caption = "DiFinish";
            //}

            foreach (GridColumn gc in gleSablon.View.Columns)
            {
                gc.FilterMode = ColumnFilterMode.DisplayText;
                gc.OptionsFilter.AutoFilterCondition = AppSession.Settings.AutoFilterCondition == "Contains" ? AutoFilterCondition.Contains : AutoFilterCondition.Like;

                if (gc.FieldName == "PhotoMikro")
                {
                    RepositoryItemPictureEdit glePic = GetPhotoRI();

                    gleSablon.View.RowHeight = 32;
                    gleSablon.View.Columns["PhotoMikro"].Width = 32;

                    gc.ColumnEdit = glePic;
                    gc.Caption = "P";
                }
            }

            return gleSablon;
        }



        static DataTable dtKons = new DataTable();
        static DataTable dtEn = new DataTable();
        static DataTable dtAgr = new DataTable();

        public static DataTable Kons
        {
            get
            {
                if (dtKons.Rows.Count == 0)
                    dtKons = Session.DataManager.ExecuteDataTable("GetDistinctValues", "Konstruksiyon");

                return dtKons;
            }
        }

        public static DataTable En
        {
            get
            {
                if (dtEn.Rows.Count == 0)
                    dtEn = Session.DataManager.ExecuteDataTable("GetDistinctValues", "EnGrubu");

                return dtEn;
            }
        }

        public static DataTable Agr
        {
            get
            {
                if (dtAgr.Rows.Count == 0)
                    dtAgr = Session.DataManager.ExecuteDataTable("GetDistinctValues", "Agirlik");

                return dtAgr;
            }
        }



        static void gleSablon_Popup(object sender, EventArgs e)
        {
            GridLookUpEdit gle = (GridLookUpEdit)sender;
            //   gle.Properties.View.BestFitColumns();
            gle.Popup -= gleSablon_Popup;
        }

        void gridview_RowStyle(object sender, RowStyleEventArgs e)
        {
            //TODO: Açılınca göstermeyeceğiz DELETED olanları.. ama eskiden girilenler listede gözükmeli.. KST yi incele.. 

            object deletedValue = (((GridView)sender).GetRowCellValue(e.RowHandle, "Deleted"));
            if (deletedValue != null && deletedValue != DBNull.Value && (bool)deletedValue)
                //e.Appearance.Font = new Font(AppearanceObject.DefaultFont, FontStyle.Strikeout);
                e.Appearance.ForeColor = Color.LightGray; // SystemColors.ControlDark;                    
        }



        public static RepositoryItem IT_Alan { get; set; }

        public static RepositoryItem IT_Lokasyon { get; set; }

        public static RepositoryItemGridLookUpEdit riEL;
        public static RepositoryItemGridLookUpEdit riEA;
        public static RepositoryItemGridLookUpEdit riEC;
        public static RepositoryItemGridLookUpEdit riCT;
        public static RepositoryItemComboBox riYaziciTipi = new RepositoryItemComboBox();
        public static RepositoryItemComboBox riBaglantiTipi = new RepositoryItemComboBox();
        public static RepositoryItemComboBox riKagitBoyutu = new RepositoryItemComboBox();

    }
}
